package com.shop.pandian.app.service.impl;

import javax.annotation.PostConstruct;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.shop.pandian.app.model.AcctRole;
import com.shop.pandian.app.model.AcctUser;
import com.shop.pandian.app.service.AcctUserService;
import com.shop.pandian.framework.vo.ShiroUser;
import com.shop.pandian.util.AppConstant;
import com.shop.pandian.util.ConvertUtil;

public class ShiroRealm extends AuthorizingRealm {

	@Autowired
	private AcctUserService acctUserService;
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		if (principals == null) {
			throw new AuthorizationException("PrincipalCollection method argement canot be null");
		}
		ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		
		AcctUser user = acctUserService.getUserByLoginName(shiroUser.loginName);
		
		info.addRoles(ConvertUtil.convertElementPropertyToList(user.getRoleList(), "roleName"));
		for (AcctRole role : user.getRoleList()) {
			info.addStringPermissions(ConvertUtil.convertElementPropertyToList(role.getAuthorityList(), "name"));
		}
		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		SimpleAuthenticationInfo info;
		try {
			UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
			AcctUser user = acctUserService.getUserByLoginName(token.getUsername());
			if (user == null) {
				throw new AuthorizationException("User " + token.getUsername() + " cannot login");
			}
			info = null;
			if (user.getLoginName().equals(token.getUsername())) {
				info = new SimpleAuthenticationInfo(new ShiroUser(user.getId(), user.getLoginName(), user.getUserName()),
						user.getPassword(), user.getLoginName());
				setSession(AppConstant.SESSION_USER_ID, user.getLoginName());

			}
			
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new AuthenticationException(e);
		}
		return info;
	}
	
	private void setSession(Object key, Object value) {
		Subject currentUser = SecurityUtils.getSubject();
		if (null != currentUser) {
			Session session = currentUser.getSession();
			System.out.println("Session默认超时时间为[" + session.getTimeout() + "]毫秒");
			if (null != session) {
				session.setAttribute(key, value);
			}
		}
	}
	
	@PostConstruct
	public void initCredentialsMatcher() {
		setCredentialsMatcher(new CustomCredentialsMatcher());

	}
	
	public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
		@Override
		public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
			UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

			String password = String.valueOf(token.getPassword());
			System.out.println("password in Realm is " + password);
			System.out.println("password in info is " + String.valueOf(info.getCredentials()));
			System.out.println("info.getCredentials " + String.valueOf(token.getPassword()));
			

			boolean result = equals(password, String.valueOf(info.getCredentials()));
			return result;
		}
	}

}
